#include "DataCent.h"
#include "StdSqlite3.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <openssl/sha.h>
#include <sqlite3.h>
#define  DBPath "./chatroom.db"

static SQL *s;

bool DataCenterInit()
{   
    s = StdSqlite3Init(DBPath);
    if(s == NULL)
    {
        return false;
    }

    char sql[] = "create table if not exists user(name text primary key,passwd text not null,salt text not null);";
    return SQLExec(s,sql);
}

bool IsUserExist(const char* name)
{
    char sql[1024] = {0};
    sprintf(sql,"select count(*) from user where name = '%s';",name);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
        return false;

    int count = atoi(result[1]);
    FreeTableInfo(result);
    return count != 0;
}

char *GenerateSlat()
{   
    srand(time(NULL));
    char salt[17] = {0};
    for(int i = 0;i < 16; i++)
    {
        salt[i] = 32 + rand() % 95;
    }
    return strdup(salt);
}

char* HashPasswd(const char*passwd,const char*salt)
{
    int newLen = strlen(passwd)+strlen(salt)+1;
    char* newPasswd = (char*)malloc(newLen);
    
    if(newPasswd == NULL)
    {
        printf("AddNewUser malloc error!\n");
        return NULL;
    }
    memset(newPasswd,0,newLen);
    strcat(newPasswd,passwd);
    strcat(newPasswd,salt);

    unsigned char hashPasswd[SHA256_DIGEST_LENGTH] = {0};
    SHA256(newPasswd,strlen(newPasswd),hashPasswd);

    char result[SHA256_DIGEST_LENGTH*2] = {0};
    for(int i = 0; i < SHA256_DIGEST_LENGTH;i++)
    {
        char temp[8] = {0};
        sprintf(temp,"%x",hashPasswd[i]);
        strcat(result,temp);
    }
    free(newPasswd);
    return strdup(result);
}

bool AddNewUser(const char *name, const char *passwd)
{   
    //生成随机颜值
    char *salt = GenerateSlat();
    char * result = HashPasswd(passwd,salt);
    char sql[1024] = {0};
    sprintf(sql,"insert into user values('%s','%s','%s');",name,result,salt);
    free(salt);
    free(result);
    return SQLExec(s,sql);
}

char*GetUserSalt(const char *name)
{ 
    char sql[1024] = {0};
    sprintf(sql,"select salt from user where name = '%s';",name);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
       return NULL;
    char *salt = strdup(result[1]);
    FreeTableInfo(result);
    return salt;
}
bool IsAccountEqual(const char *name, const char *passwd)
{   
    char sql[1024] = {0};
    char *salt = GetUserSalt(name);
    if(salt == NULL)
        return NULL;
    char *hashpasswd = HashPasswd(passwd,salt);
    sprintf(sql,"select count(*) from user where name = '%s' and passwd = '%s';",name,hashpasswd);
    free(hashpasswd);
    free(salt);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
        return false;

    int count = atoi(result[1]);
    FreeTableInfo(result);
    return count != 0;
    
}

// void insertName(const char FromName)
// {
//     char sql[1024] = {0};
//     sprintf(sql,"update user set is_online = 1 where name = '%s';",FromName);
//     return SQLExec(s,sql);
// }

// 创建好友表
bool CreateFriendshipTable() 
{   
    s = StdSqlite3Init(DBPath);
    if(s == NULL)
    {
        return false;
    }
    char sql[] = "create table if not exists friendship (self_name text not null,friend_name text not null,is_friend integer not null);";
    return SQLExec(s,sql);
}

bool AddFriend(const char* self_name,const char*friend_name,const char*is_friend)
{   
    char sql[1024] = {0};
    sprintf(sql,"insert into friendship values ('%s', '%s', 0);",self_name,friend_name,is_friend);
    return SQLExec(s,sql);
}

int WeatherHavePerson(const char *friend_name)
{
    char sql[1024] = {0};
    sprintf(sql,"select count(*) from user where name ='%s';", friend_name);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
        return false;

    int count = atoi(result[1]);
    FreeTableInfo(result);
    return count != 0;
}

bool AlreadyFriends(const char *self_name, const char *friend_name)
{
    char sql[1024] = {0};
    sprintf(sql,"select count(*) from friendship where ( self_name ='%s'and friend_name = '%s' ) or ( friend_name = '%s' and self_name = '%s');", self_name, friend_name,self_name,friend_name);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
        return false;

    int count = atoi(result[1]);
    FreeTableInfo(result);
    return count != 0;
}
char** FriendRequest(const char*friend_name)
{   
    char sql[1024] = {0};
    sprintf(sql,"select self_name from friendship where friend_name = '%s' and is_friend = 0;",friend_name);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
        return false;
    return  result;
}
int GetTheTotalNumberOfFriendRequests(const char*friend_name)
{
    char sql[1024] = {0};
    sprintf(sql,"select count(*) from friendship where friend_name = '%s' and is_friend = 0;",friend_name);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
        return false;
    int count = atoi(result[1]);
    FreeTableInfo(result);
    return count;
}
// 处理好友申请
bool ProcessFriendRequest(const char *self_name, const char *friend_name, const char* decision)
 {  
    int f = atoi(decision);
    char sql[200];
    if (f == 1) 
    {
        sprintf(sql, "update friendship set is_friend = 1 where self_name = '%s' and friend_name = '%s';", friend_name, self_name);
        return SQLExec(s,sql);
    } 
    if(f == 0)
    {
        sprintf(sql, "delete from friendship where self_name = '%s' and friend_name = '%s';", friend_name, self_name);
        return SQLExec(s,sql);
    } 
 }
 //获取好友列表
char**GetFriendList1(const char*self_name)
 {
    char sql[1024] = {0};
    sprintf(sql,"select friend_name  from friendship where self_name = '%s' and is_friend = 1;", self_name);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
        return false;
    return  result;
 }

char**GetFriendList2(const char*friend_name)
 {
    char sql[1024] = {0};
    sprintf(sql,"select self_name  from friendship where friend_name = '%s' and is_friend = 1;", friend_name);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
        return false;
    return  result;
 }

int AlreadyFriendsCounts1(const char *self_name)
{
    char sql[1024] = {0};
    sprintf(sql,"select count(*) from friendship where  self_name ='%s' and is_friend = 1;", self_name );
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
        return false;

    int count = atoi(result[1]);
    FreeTableInfo(result);
    return count;
}

int AlreadyFriendsCounts2(const char *self_name)
{
    char sql[1024] = {0};
    sprintf(sql,"select count(*) from friendship where  friend_name ='%s' and is_friend = 1;", self_name );
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
        return false;

    int count = atoi(result[1]);
    FreeTableInfo(result);
    return count;
}

bool IsAlreadyFriends(const char *self_name, const char *friend_name)
{
    char sql[1024] = {0};
    sprintf(sql,"select count(*) from friendship where (( self_name ='%s'and friend_name = '%s' ) or ( friend_name = '%s' and self_name = '%s')) and is_friend = 1;", self_name, friend_name,self_name,friend_name);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
        return false;

    int count = atoi(result[1]);
    FreeTableInfo(result);
    return count != 0;
}

bool DeleteFriend(const char*self_name,const char*friend_name)
{   
    char sql[1024] = {0};
    sprintf(sql, "delete from friendship where self_name = '%s' and friend_name = '%s';", self_name, friend_name);
    char sql1[1024] = {0};
    sprintf(sql1, "delete from friendship where self_name = '%s' and friend_name = '%s';", friend_name, self_name);
    return (SQLExec(s, sql) || SQLExec(s, sql1));

}

//创建群聊表
bool CreateGroupRelationshipTable() 
{   
    s = StdSqlite3Init(DBPath);
    if(s == NULL)
    {
        return false;
    }
    char sql[] = "create table if not exists grouprelationship (group_name text not null,group_id text not null,creator_name text not null,group_member text not null,is_group integer not null);";
    return SQLExec(s,sql);
}

bool CreateGroupChat(const char* group_name,const char*group_id,const char*creator_name)
{   
    char sql[1024] = {0};
    sprintf(sql,"insert into grouprelationship values ('%s', '%s','%s','%s', 1);",group_name,group_id,creator_name,creator_name);
    return SQLExec(s,sql);
}

int WeatherHasGroup(const char* group_id)
{
    char sql[1024] = {0};
    sprintf(sql,"select count(*) from grouprelationship where  group_id = '%s';",group_id);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
        return false;
    int count = atoi(result[1]);
    FreeTableInfo(result);
    return count;
}


char** QueryGroupName(const char* group_name)
{
    char sql[1024] = {0};
    sprintf(sql,"select group_name  from grouprelationship where group_member = '%s' and is_group = 1;", group_name);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
       return false;
    return  result;
}

char** QueryGroupId(const char* group_id)
{
    char sql[1024] = {0};
    sprintf(sql,"select group_id  from grouprelationship where group_member = '%s' and is_group = 1;", group_id);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
       return false;
    return  result;
}

char** QueryCreatorName(const char* creator_name)
{
    char sql[1024] = {0};
    sprintf(sql,"select creator_name from grouprelationship where group_member = '%s' and is_group = 1;",creator_name);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
       return false;
    return  result;
}

int GroupChatNumber(const char *self_name)
{
    char sql[1024] = {0};
    sprintf(sql,"select count(*) from grouprelationship where  group_member ='%s' and is_group = 1;", self_name );
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
        return false;

    int count = atoi(result[1]);
    FreeTableInfo(result);
    return count;
}

char* itoa(int value, char* str, int base) 
{
    int i = 0;
    bool isNegative = false;
    
    // 将整数逐位转换为字符，存储到结果字符串中
    while (value != 0) 
    {
        int remainder = value % base;
        str[i++] = remainder + '0';
        value /= base;
    }

    // 反转结果字符串
    int j = 0;
    while (j < i / 2) 
    {
        char temp = str[j];
        str[j] = str[i - j - 1];
        str[i - j - 1] = temp;
        j++;
    }

    // 在结果字符串末尾添加空字符 '\0'
    str[i] = '\0';
    
    return str;
}

int WeatherGroupAdded(const char* group_member,const char* group_name,const char* group_id,const char* creator_name)
{
    char sql[1024] = {0};
    sprintf(sql,"select count(*) from grouprelationship where group_member = '%s' and group_name = '%s' and group_id = '%s' and creator_name = '%s';",group_member,group_name,group_id,creator_name);
   char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
        return false;
    int count = atoi(result[1]);
    FreeTableInfo(result);
    return count;
}

bool ApplyGroupChat(const char* group_member,const char* group_name,const char*group_id,const char*creator_name)
{   
    char sql[1024] = {0};
    sprintf(sql,"insert into grouprelationship values ('%s', '%s','%s','%s', '0');",group_name,group_id,creator_name,group_member);
    return SQLExec(s,sql);
}

int WeatherHaveGroup(const char* group_name,const char* group_id,const char* creator_name)
{
    char sql[1024] = {0};
    sprintf(sql,"select count(*) from grouprelationship where group_name = '%s' and group_id = '%s' and creator_name = '%s';",group_name,group_id,creator_name);
   char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
        return false;
    int count = atoi(result[1]);
    FreeTableInfo(result);
    return count;
}

int WeatherGroupExit(const char* group_member,const char* group_name,const char* group_id,const char* creator_name)
{
    char sql[1024] = {0};
    sprintf(sql,"select count(*) from grouprelationship where group_member = '%s' and group_name = '%s' and group_id = '%s' and creator_name = '%s' and is_group = 1;",group_member,group_name,group_id,creator_name);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
        return false;
    int count = atoi(result[1]);
    FreeTableInfo(result);
    return count;
}

bool ExitGroupChat(const char* group_member,const char* group_name,const char* group_id,const char* creator_name)
{
    char sql[1024] = {0};
    sprintf(sql, "delete from grouprelationship where group_member = '%s' and group_name = '%s' and group_id = '%s' and creator_name = '%s' and is_group = 1;",group_member,group_name,group_id,creator_name);
    return SQLExec(s,sql);
}

bool DeleteGroupChat(const char* group_name,const char* group_id,const char* creator_name)
{
    char sql[1024] = {0};
    sprintf(sql, "delete from  grouprelationship where group_name = '%s' and group_id = '%s' and creator_name = '%s';",group_name,group_id,creator_name);
    return SQLExec(s,sql);
}

char** QueryGroupName1(const char* group_name)
{
    char sql[1024] = {0};
    sprintf(sql,"select group_name  from grouprelationship where creator_name = '%s' and is_group = 0;", group_name);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
       return false;
    return  result;
}

char** QueryGroupId1(const char* group_id)
{
    char sql[1024] = {0};
    sprintf(sql,"select group_id  from grouprelationship where creator_name = '%s' and is_group = 0;", group_id);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
       return false;
    return  result;
}

char** QueryGroupMember(const char* group_member)
{
    char sql[1024] = {0};
    sprintf(sql,"select group_member from grouprelationship where creator_name = '%s' and is_group = 0;",group_member);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
       return false;
    return  result;
}

int ApplyGroupChatNumber(const char *self_name)
{
    char sql[1024] = {0};
    sprintf(sql,"select count(*) from grouprelationship where  creator_name = '%s' and is_group = 0;", self_name );
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
        return false;

    int count = atoi(result[1]);
    FreeTableInfo(result);
    return count;
}

// 处理群聊申请
bool ProcessGroupChatRequest(const char *group_name, const char *group_id,const char*creator_name,const char*group_member, const char* decision)
 {  
    int f = atoi(decision);
    char sql[200];
    if (f == 1) 
    {
        sprintf(sql, "update grouprelationship set is_group = 1 where group_name = '%s' and group_id = '%s' and creator_name = '%s' and group_member = '%s';", group_name,group_id,creator_name,group_member);
        return SQLExec(s,sql);
    } 
    if(f == 0)
    {
        sprintf(sql, "delete from grouprelationship where  group_name = '%s' and group_id = '%s' and creator_name = '%s' and group_member = '%s' and is_group = 0;", group_name,group_id,creator_name,group_member);
        return SQLExec(s,sql);
    } 
 }

int InviteGroupChatNumber(const char *group_name,const char *group_id,const char *creator_name,const char*group_member)
{
    char sql[1024] = {0};
    sprintf(sql,"select count(*) from grouprelationship where group_name = '%s' and group_id = '%s' and creator_name = '%s' and group_member = '%s' and is_group = 1;", group_name,group_id,creator_name,group_member );
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
        return false;

    int count = atoi(result[1]);
    FreeTableInfo(result);
    return count;
}

bool InviteGroupChat(const char *group_name, const char *group_id,const char*creator_name,const char*group_member)
{
    char sql[1024] = {0};
    sprintf(sql,"insert into grouprelationship values ('%s', '%s','%s','%s', '1');",group_name,group_id,creator_name,group_member);
    return SQLExec(s,sql);
}

//创建好友消息列表
bool CreateFriendMessagesTable() 
{   
    s = StdSqlite3Init(DBPath);
    if(s == NULL)
    {
        return false;
    }
    char sql[] = "create table if not exists friendmessages (id integer primary key autoincrement,send_name text not null,receiver_name text not null,message text not null,timestamp datatime default current_timestamp,read_status integer not null);";
    return SQLExec(s,sql);
}

int WeatherFriendship(const char *self_name,const char *friend_name)
{
    char sql[1024] = {0};
    sprintf(sql,"select count(*) from friendship where (self_name = '%s' and friend_name = '%s' and is_friend = 1) or (friend_name = '%s' and self_name = '%s' and is_friend = 1);", self_name,friend_name,self_name,friend_name);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
        return false;
    int count = atoi(result[1]);
    FreeTableInfo(result);
    return count;
}

char** FriendSendname(const char* receiver_name)
{
    char sql[1024] = {0};
    sprintf(sql,"select send_name from friendmessages where receiver_name = '%s' and read_status = 0;", receiver_name);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
       return false;
    return  result;
}

char** FriendMessage(const char* receiver_name)
{
    char sql[1024] = {0};
    sprintf(sql,"select message from friendmessages where receiver_name = '%s' and read_status = 0;", receiver_name);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
       return false;
    return  result;
}

char** FriendTimestamp(const char* receiver_name)
{
    char sql[1024] = {0};
    sprintf(sql,"select timestamp from friendmessages where receiver_name = '%s' and read_status = 0;", receiver_name);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
       return false;
    return  result;
}

int FriendMessageNumber(const char* receiver_name)
{
    char sql[1024] = {0};
    sprintf(sql,"select count(*) from friendmessages where receiver_name = '%s' and read_status = 0;", receiver_name);
    char **result = GetTableInfo(s,sql,NULL,NULL);
    if(result == NULL)
        return false;
    int count = atoi(result[1]);
    FreeTableInfo(result);
    return count;
}

bool UpdateStatusMessages(const char* receiver_name)
{  
    char sql[200];
    sprintf(sql, "update friendmessages set read_status = 1 where receiver_name = '%s';",receiver_name);
    return SQLExec(s,sql);
}

bool AddFriendMessage(const char *send_name, const char *receiver_name,const char*message)
{
    char sql[1024] = {0};
    sprintf(sql,"insert into friendmessages (send_name,receiver_name,message,read_status) values ('%s', '%s','%s',0);",send_name,receiver_name,message);
    return SQLExec(s,sql);
}

//创建群聊消息列表
bool CreateGroupMessagesTable() 
{   
    s = StdSqlite3Init(DBPath);
    if(s == NULL)
    {
        return false;
    }
    char sql[] = "create table if not exists groupmessages (id integer primary key autoincrement,send_name text not null,group_id text not null,group_member text not null,message text not null,timestamp datatime default current_timestamp,read_status integer not null);";
    return SQLExec(s,sql);
}
